<script setup lang="ts">
import type { ProjectBaseInfo } from "@/common/apis/dashboard/type"
import type { CheckboxValueType, FormInstance, FormRules } from "element-plus"
import { detailDataApi, editDataApi, saveDataApi } from "@/common/apis/dashboard"
import { moduleNameText, moduleOptions, moduleValue } from "@/common/apis/dashboard/type"
import { setProjectInfo } from "@/common/utils/cache/local-storage"
import { FormTypeEnum } from "@@/constants/other-keys"
import { ElMessage, ElMessageBox } from "element-plus"
import { cloneDeep, isEqual } from "lodash-es"
import { computed, ref, watch } from "vue"

interface Props {
  id: string | undefined
  dialogType: FormTypeEnum
  visible: boolean
}

const props = withDefaults(defineProps<Props>(), {
  dialogType: FormTypeEnum.VIEW
})
const emit = defineEmits(["closeDialog"])
const DEFAULT_FORM_DATA: ProjectBaseInfo = {
  project_id: undefined,
  project_name: "",
  project_modules: [],
  project_describe: ""
}
const dialogVisible = ref<boolean>(false)
const formRef = ref<FormInstance | null>(null)
const formData = ref<ProjectBaseInfo>(cloneDeep(DEFAULT_FORM_DATA))
const formRules: FormRules<ProjectBaseInfo> = {
  project_name: [{ required: true, trigger: "blur", message: "请输入" }],
  project_modules: [{ required: true, trigger: "change", message: "请选择模块" }]
}
const loading = ref<boolean>(false)
const detailLoading = ref<boolean>(false)
const isEdit = ref<boolean>(false)
const defaultFormData = ref<ProjectBaseInfo>(cloneDeep(DEFAULT_FORM_DATA))

const checkAll = ref(false)
const isIndeterminate = ref(false)

const textMap = computed(() => {
  if (props.dialogType === FormTypeEnum.CREATE) return "新建项目"
  else if (props.dialogType === FormTypeEnum.EDIT) return "编辑项目"
  else return "项目信息"
})
function getProjectInfo() {
  detailLoading.value = true
  props.id
  && detailDataApi(props.id)
    .then(({ data }) => {
      if (data) {
        formData.value = {
          project_id: data.project_id,
          project_name: data.project_name,
          project_modules: JSON.parse(data.project_modules),
          project_describe: data.project_describe
        }
        setCheckStatus()
        defaultFormData.value = cloneDeep(formData.value)
      } else {
        ElMessage("数据不存在")
      }
    })
    .finally(() => {
      detailLoading.value = false
    })
}
function showDialog() {
  formRef.value?.resetFields()
  isEdit.value = false
  detailLoading.value = false
  formData.value = cloneDeep(DEFAULT_FORM_DATA)
  if (props.dialogType !== FormTypeEnum.CREATE) {
    getProjectInfo()
  } else {
    setCheckStatus()
  }
}
function closeDialog(type?: string) {
  formRef.value?.resetFields()
  emit("closeDialog", type)
}
function handleConfirm() {
  formRef.value?.validate(async (valid: boolean, fields) => {
    if (!valid) return console.error("表单校验不通过", fields)
    loading.value = true
    saveDataApi(formData.value)
      .then(({ data }) => {
        ElMessage.success("操作成功")
        formData.value.project_id = data.project_id
        setProjectInfo(JSON.stringify(formData.value))
        closeDialog("redirect")
      })
      .finally(() => {
        loading.value = false
      })
  })
}
function handleCloseTip(done: () => void) {
  if (props.dialogType === FormTypeEnum.VIEW && !isEdit.value) {
    closeDialog()
    done()
    return
  }
  // 校验值是否相同
  if (isEqual(defaultFormData.value, formData.value)) {
    closeDialog()
    done()
    return
  }
  ElMessageBox.confirm("当前编辑未保存，是否确定关闭？").then(() => {
    done()
  })
}
function handleEdit() {
  defaultFormData.value = cloneDeep(formData.value)
  setCheckStatus()
  isEdit.value = true
}
function handleEditCancel() {
  isEdit.value = false
  getProjectInfo()
}
function handleEditSave() {
  formRef.value?.validate(async (valid: boolean, fields) => {
    if (!valid) return console.error("表单校验不通过", fields)
    loading.value = true
    editDataApi(formData.value)
      .then(() => {
        ElMessage.success("操作成功")
        isEdit.value = false
        setProjectInfo(JSON.stringify(formData.value))
      })
      .finally(() => {
        loading.value = false
      })
  })
}
function handleCheckAllChange(val: CheckboxValueType) {
  formData.value.project_modules = val ? moduleValue : []
  isIndeterminate.value = false
}
function handleCheckedCitiesChange(value: CheckboxValueType[]) {
  const checkedCount = value.length
  checkAll.value = checkedCount === moduleOptions.length
  isIndeterminate.value = checkedCount > 0 && checkedCount < moduleOptions.length
}
function setCheckStatus() {
  const checkedCount = formData.value.project_modules.length
  checkAll.value = checkedCount === moduleOptions.length
  isIndeterminate.value = checkedCount > 0 && checkedCount < moduleOptions.length
}

watch(
  () => [props.id, props.dialogType, props.visible],
  () => {
    dialogVisible.value = props.visible
    if (props.visible) {
      showDialog()
    }
  }
)
watch(
  () => [props.id, props.dialogType],
  () => {
    formData.value = cloneDeep(DEFAULT_FORM_DATA)
    defaultFormData.value = cloneDeep(formData.value)
    if (props.dialogType !== FormTypeEnum.CREATE) {
      getProjectInfo()
    }
  }
)
</script>

<template>
  <el-drawer
    v-model="dialogVisible"
    direction="rtl"
    size="600px"
    @close-auto-focus="closeDialog"
    @close="closeDialog"
    :before-close="handleCloseTip"
    :show-close="false"
  >
    <template #header>
      <div class="drawer-header">
        <h4>{{ textMap }}</h4>
        <el-space>
          <el-button v-if="isEdit" @click="handleEditCancel">
            取消保存
          </el-button>
          <el-button v-if="isEdit" type="primary" v-throttle="() => handleEditSave()">
            保存
          </el-button>
          <el-button v-if="!isEdit && props.dialogType == FormTypeEnum.VIEW" type="primary" @click="handleEdit">
            编辑
          </el-button>
        </el-space>
      </div>
    </template>
    <template #default>
      <el-form
        v-if="dialogType != FormTypeEnum.VIEW || isEdit"
        ref="formRef"
        :model="formData"
        :rules="formRules"
        width="600"
        label-width="120px"
        label-position="right"
        :close-on-click-modal="false"
        v-loading="detailLoading"
      >
        <el-form-item label="项目名称" prop="project_name">
          <el-input v-model="formData.project_name" autocomplete="off" placeholder="请输入" />
        </el-form-item>
        <el-form-item label="选择模块" prop="project_module">
          <el-checkbox v-model="checkAll" :disabled="isEdit && defaultFormData.project_modules.length == moduleOptions.length" :indeterminate="isIndeterminate" @change="handleCheckAllChange">
            全选
          </el-checkbox>
          <el-checkbox-group v-model="formData.project_modules" @change="handleCheckedCitiesChange">
            <el-checkbox v-for="city in moduleValue" :key="city" :label="moduleNameText[city]" :value="city" :disabled="isEdit && defaultFormData.project_modules.includes(city)">
              {{ moduleNameText[city] }}
            </el-checkbox>
          </el-checkbox-group>
        </el-form-item>
        <el-form-item label="项目描述" prop="project_describe">
          <el-input
            v-model="formData.project_describe"
            :rows="3"
            type="textarea"
            placeholder="请输入"
            maxlength="600"
          />
        </el-form-item>
      </el-form>

      <el-form
        v-else
        width="600"
        label-width="120px"
        label-position="right"
        :close-on-click-modal="false"
        v-loading="detailLoading"
        class="custom-view-form"
      >
        <el-form-item label="项目名称：">
          {{ $getViewText(formData.project_name) }}
        </el-form-item>
        <el-form-item label="模块：">
          <el-space wrap>
            <el-tag v-for="city in formData.project_modules" :key="city" :label="moduleNameText[city]" :value="city">
              {{ moduleNameText[city] }}
            </el-tag>
          </el-space>
        </el-form-item>
        <el-form-item label="项目描述：">
          {{ $getViewText(formData.project_describe) }}
        </el-form-item>
      </el-form>
    </template>
    <template v-if="dialogType !== FormTypeEnum.VIEW" #footer>
      <div class="dialog-footer">
        <el-button plain @click="closeDialog()">
          取 消
        </el-button>
        <el-button :loading="loading" type="primary" @click="handleConfirm">
          确 定
        </el-button>
      </div>
    </template>
    <template v-else #footer>
      <div class="dialog-footer">
        <el-button plain @click="closeDialog()">
          关 闭
        </el-button>
      </div>
    </template>
  </el-drawer>
</template>

<style lang="scss" scoped>
.upload-demo {
  width: 100% !important;
}
:deep(.el-upload.el-upload--text) {
  width: 100% !important;
}
</style>
